Menus is a crucial part of integrating with the operating systems user interface, so in this lesson,
we'll see how to create unique menus for our electron app using two modules, the menu and menu item
modules.
As the name suggests, an instance of a menu will be populated with menu items.
So let's see this with a basic example.
As always, I'll start by requiring those two modules from electronic menu and menu item, both with
capital M's.
As these modules expose classes, then step one is creating a menu which we can fill with menu items.
Let main menu equal new menu next week in full.
This main menu with some menu items create a new menu item.
Menu item one equal new menu item.
This takes an object with properties for this menu item, I'll only set the label for now electron this
being what the item will show up as in the menu.
Now, before I continue, it's very important to understand the differences between up menus in Windows,
Mac and Linux.
The most significant of these differences being that on Mac, the first menu item will always be labelled
the name of the application.
In this case, that happens to be electron as a label that year.
But very important to keep in mind, the documentation covers these differences in more detail and will
see it when building our first project up in later lessons.
Just something to be aware of for now.
OK, we have a menu and we have a menu item to add to this menu.
So the first way of doing this is with the menus.
Append instance method, main menu, append menu item one.
And finally, we have to tell our app to use main menu as the main application menu for this.
The app needs to be ready.
So in create a window, seeing as that is executed on the ready event called the menu class a static
set application menu method passing in main menu.
Let's recap.
We create a menu instant with Electron's menu class assigning a two main menu.
Then we create a single menu item with a label of electron, this time using the menu item class.
Instead we add that menu item, instant menu item one to the end of main menu.
We only have the one though, so end or beginning is all the same.
And finally we tell Electron to use main menu as the main top level menu for the app.
Save this, and there we have it all the standard menu items we had before is now gone and instead we
have the single item with a label of electron right now, this having no logic attached to it at all.
What we generally expect from a top level menu item such as this, then, is to get a dropdown of related
menu items when clicked, this dropdown being referred to as a submenu.
So let's add one in the menu item one constructor.
Set the submenu property to an array.
In which we can now add more menu items now, we could again create these menu items with the menu item
class, as we did here, but instead, Electron allows us to specify menu templates, menu templates,
essentially being menu item constructor objects such as this one we we're working in.
So add an object to this submenu array, this representing a single menu item with a label of item one,
duplicate that a couple of times.
Item two and item three save.
We still only see menu item one as that's the top level menu item, but when I click it, we're presented
with item one, two and three in a dropdown or submenu.
Each of these new menu items being the exact same menu item instanced type as our original menu item
one, meaning they can again contain their own submenus on item to set submenu an array with a new menu
item object labeled sub item one save.
Click the top level menu item item to now having an arrow to indicate it contains submenu items, hover
on that and there another submenu with Subba item one.
This can go infinitely deep, but usually two to three levels is the maximum recommended depth as things
can get a bit confusing.
So defining menu items using these object templates is a lot simpler then.
And luckily, Electron also allows us to do this for top level items instead of creating them individually
and sending them to the menu, for instance, like this to do this weekend.
Instead of creating a new menu, for instance, use the menu classes pulled from template static method
in which will describe the entire menu structure for main menu exactly as we did here.
This takes an array like a submenu.
Cut the constructor object for menu item one, that single top level item, we also no longer need this
append method and paste into the template array, the entire object.
There's still being the one and only top level menu item in main menu, but it's much more logical in
its structure.
Now, add a second top level item in the template array.
Call this actions with its own submenu.
In the submenu, add a menu item labeled Action One.
Duplicate that twice, action to and action three save.
And now we have that second menu item in our main menu, actions containing a submenu with three more
menu items.
So the hierarchy and structure of menus is fairly logical then and using the build from template method,
as we've just done, allows us to structure menus very easily.
It also allows us to better organize our code.
For example, this entire main menu array can now be moved outside of Main Doges into its own module.
I'll create a new file main menu dot js in which we can export the array, making up the structure of
main menu.
We do this by setting on the module docked export property.
So a standard node module.
The main menu template array.
And so now when we require this new main menu module, we're simply given this array requiring enabled
from template function, dot slash.
So in the current directory, main menu, no need to specify the JS extension node will figure that
out.
Save.
And the menu works as before, but we've made our code significantly more organized, the next logical
step then is to add some functionality to these menu items, for example, a function that fires when
a menu item is clicked on action three, all at a click property, which takes a function to call.
When this item is clicked, I'll use an anonymous function to demonstrate with a log message of hello
from Main Menu.
Change the label to match great, save this.
And now when I click greet in the actions submenu, we see that logged in the terminal hello from Main
Menu.
So we can very easily add just about any logic on a menu item.
We can also automatically assign this menu item, a keyboard shortcut using an accelerator string as
before said the menu items accelerator property to shift plus ult plus G or Garet save.
And before trigger the great click via the keyboard, noticed that electron is now also automatically
added the accelerator string to the great items label, very useful for letting the user know that this
can be accessed with a keyboard shortcut.
Try that shift alt g, check the terminal.
And as before we have that log message.
Very importantly, keep in mind that menu item shortcuts are not global.
As in the previous lesson, global shortcuts can only be registered with the global shortcut module
for menu item shortcuts.
To work that up must be in focus, which is the expected behavior.
Of course, another useful menu item property is the ability to disable certain items.
I'll disable action to.
Setting enabled to false save.
And that item is great out and no longer clickable, useful for menu actions with certain prerequisites.
Finally, we have menu item rolls.
Rolls are predefined menu items that electron provides in a unique way, depending on the user's operating
system.
For example, I'll change action one to dev tools.
With a roll of toggle dev tools, nothing else.
We see the label with an automatically generated shortcut outcome on a on Mac, which will automatically
be set to alt control on Windows and Linux, click that and the dev tools is closed or toggled on and
off as the roll suggests.
Click it again and it's back.
Some rolls even going as far as providing us with the label as well.
Like the full screen roll.
I'll change the second menu item in actions to have a single property of roll toggle full screen.
And there we get a label shortcut and of course, the associated functionality fullscreen.
And back to normal.
Electron provides us with many of these pre configured roles to see a list navigate on the menu item
documentation page right at the top here, two rolls.
There are a lot of standard behavior items, including things like undo, redo, copy, paste, etc..
Let's see some of those.
I'll add a new menu item in the second position of the main menu, a typical location for the edit menu,
which is what a label this gif.
Edit a submenu with a roll item of undo.
Redo.
Copy and paste, I'll add a text area to demonstrate on open index, not html add immediately after
the heading text area save.
And also main menu, I'll close the dev tools from the menu to allow us to see the entire text area,
and when we inspect this edit menu, notice that electron also took the liberty of adding a dictation
role and access to emojis and symbols, this being a result of the copy and paste roles in this menu.
Add something to this text area, some test text.
I like that copy.
Then paste, which does what we'd expect.
Try undo.
And again, our base commands are reverted note that we could have also said a single edit menu roll
to get all of this behavior automatically.
So definitely worth having a look through these menu item rolls in the next list.
And we'll take the menus one step further and see how to create context menus on right click.